package com.orhon.smartcampus.modules.core.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.CompleteMultipartUploadRequest;
import com.aliyun.oss.model.CompleteMultipartUploadResult;
import com.aliyun.oss.model.InitiateMultipartUploadRequest;
import com.aliyun.oss.model.InitiateMultipartUploadResult;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PartETag;
import com.aliyun.oss.model.UploadPartRequest;
import com.aliyun.oss.model.UploadPartResult;
import com.orhon.smartcampus.utils.MultipartFileToFile;
import com.orhon.smartcampus.utils.OSSUtil;
import com.orhon.smartcampus.utils.R;
import com.orhon.smartcampus.utils.TypeDict;

import net.coobird.thumbnailator.Thumbnails;

@RestController
@RequestMapping("/file")
public class FileController {

	@Value("${fileserver.url}")
	private String url;

	@RequestMapping("/upload") 
	public R test(@RequestParam("file") MultipartFile[] files) {
		ArrayList<Object> list = new ArrayList<Object>();

		try {

			for (MultipartFile file : files) {
				HashMap<String,String> map = new HashMap<String, String>();
				long  startTime=System.currentTimeMillis();
				System.out.println("fileName："+file.getOriginalFilename());
				SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd");
				String data = ft.format(new Date());
				String newFileName = new Date().getTime()+file.getOriginalFilename();
				String path=url+data+"/"+newFileName;
				File newFile=new File(path);
				//通过CommonsMultipartFile的方法直接写文件（注意这个时候）
				if(!newFile.getParentFile().exists()){
					try {
						newFile.getParentFile().mkdirs();
						newFile.createNewFile();
						System.out.println("创建成功!");
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				file.transferTo(newFile);
				long  endTime=System.currentTimeMillis();
				System.out.println("上传时间时间："+String.valueOf(endTime-startTime)+"ms");

				map.put("Name", file.getOriginalFilename());
				map.put("newName", data+"/"+newFileName);
				//判断是否是图片
				if(TypeDict.fileType(path)) {
					Thumbnails.of(path) 
					.scale(1f) 
					.outputQuality(0.2f) 
					.toFile(url+data+"/"+"thumb-"+newFileName);
					map.put("newThumbName", data+"/"+"thumb-"+newFileName);
				}

				list.add(map);
			}
			return R.ok().put("data", list);
		} catch (IOException e) {
			System.out.println(e);
			R.error().put("msg", "未知错误");
		}
		return R.error();



	}

	/**
	 * 下载
	 * @param request
	 * @param response
	 * @param filename
	 * @return
	 */
	@RequestMapping("/down") 
	public void downFile(HttpServletRequest request, 
			HttpServletResponse response,String filename) { 
		// 得到要下载的文件名 

		try { 
			//filename = new String(filename.getBytes("iso8859-1"), "UTF-8"); 

			// 得到要下载的文件 
			File file = new File(url  + filename); 
			System.out.println(file);
			// 如果文件不存在 
			if (!file.exists()) { 
				request.setAttribute("message", "您要下载的资源已被删除！！"); 
				System.out.println("您要下载的资源已被删除！！"); 
				return ; 
			} 
			// 处理文件名 
			String realname = filename.substring(13); 

			// 读取要下载的文件，保存到文件输入流 
			FileInputStream in = new FileInputStream(url + filename); 
			// 创建输出流 
			OutputStream out = response.getOutputStream(); 

			String ext = filename.substring(filename.indexOf(".")+1);
			//判断文件格式,设置相应的输出文件格式
			if (ext.equals("jpg") || ext.equals("JPG") || ext.equals("tiff")||
					"tif".equals(ext)||"TIF".equals(ext)||"TIFF".equals(ext)) {
				response.setContentType("image/jpeg");
			} else if (ext.equals("png") || ext.equals("PNG")) {
				response.setContentType("image/png");
			} else if (ext.equals("pdf") || ext.equals("PDF")) {
				response.setContentType("application/pdf");
			}else {
				// 设置响应头，控制浏览器下载该文件 
				response.setHeader("content-disposition", "attachment;filename="
						+ URLEncoder.encode(realname, "UTF-8")); 
			}

			// 创建缓冲区 
			byte buffer[] = new byte[1024* 10]; 
			int len = 0; 
			// 循环将输入流中的内容读取到缓冲区当中
			System.out.println("流循环读开始!"+new Date().toString());
			while ((len = in.read(buffer)) > 0) { 
				// 输出缓冲区的内容到浏览器，实现文件下载 
				out.write(buffer, 0, len); 
			} 
			System.out.println("流循环读结束!"+new Date().toString());
			// 关闭文件输入流 
			in.close(); 
			// 关闭输出流 
			out.close(); 
		} catch (Exception e) { 
		} 
	} 


	@RequestMapping("/ossupload") 
	public R ossupload(@RequestParam("file") MultipartFile[] files) throws Exception {
		ArrayList<Object> list = new ArrayList<Object>();
		
		for (MultipartFile file : files) {
			HashMap<String,String> map = new HashMap<String, String>();
			File toFile = MultipartFileToFile.multipartFileToFile(file);
			String newName = new Date().getTime()+toFile.getName();
			OSSClient ossClient = OSSUtil.getOSSClient();
			FileInputStream in = new FileInputStream(toFile); 
			String string = TypeDict.getTypeByStream1(in);
			String newurl = OSSUtil.uploadByFile(ossClient,toFile, "orhon-smartcloud", url+string+"/"+newName);
			map.put("Name", file.getOriginalFilename());
			map.put("newName", newurl);
			//判断是否是图片
//			if(TypeDict.ossfileType(url+newName)) {
//				Thumbnails.of(toFile).scale(1f).outputQuality(0.2f).toFile(toFile);
//				OSSClient ossClient1 = OSSUtil.getOSSClient();
//				String newThumburl = OSSUtil.uploadByFile(ossClient1,toFile, "orhon-smartcloud", url+"thumb-"+newName);
//				map.put("newThumbName", newThumburl);
//			}
			toFile.delete();
			list.add(map);
		}
		return R.ok().put("data", list);
	}
	
	

	@RequestMapping("/ossupload1") 
	public void ossupload(@RequestParam("file") MultipartFile file) throws Exception {

		
		String endpoint = "oss-cn-huhehaote.aliyuncs.com";
		// 阿里云主账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维，请登录https://ram.console.aliyun.com 创建RAM账号。
		String accessKeyId = "LTAI4Fx7rF6t6LZFhTMztyon";
		String accessKeySecret = "EGEjdYUIAm9V9Tw7zIpTQlLx7C0o2L";
		
		String bucketName = "orhon-smartcloud";
		// <yourObjectName>表示上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
		File toFile = MultipartFileToFile.multipartFileToFile(file);
		String newName = "Ceshi"+new Date().getTime()+toFile.getName();
		String objectName = url+newName;
		
		

		// 创建OSSClient实例。
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);

		// 创建InitiateMultipartUploadRequest对象。
		InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest("orhon-smartcloud", objectName);

		// 如果需要在初始化分片时设置文件存储类型，请参考以下示例代码。
		 ObjectMetadata metadata = new ObjectMetadata();
		 //metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
		 metadata.setContentType("image/jpg");
		 request.setObjectMetadata(metadata);

		// 初始化分片。
		InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request);
		// 返回uploadId，它是分片上传事件的唯一标识，您可以根据这个ID来发起相关的操作，如取消分片上传、查询分片上传等。
		String uploadId = upresult.getUploadId();

		// partETags是PartETag的集合。PartETag由分片的ETag和分片号组成。
		List<PartETag> partETags =  new ArrayList<PartETag>();
		// 计算文件有多少个分片。
		final long partSize = 1 * 1024 * 1024L;   // 1MB
		long fileLength = toFile.length();
		int partCount = (int) (fileLength / partSize);
		if (fileLength % partSize != 0) {
		    partCount++;
		 }
		// 遍历分片上传。
		for (int i = 0; i < partCount; i++) {
		    long startPos = i * partSize;
		    long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
		    InputStream instream = new FileInputStream(toFile);
		    // 跳过已经上传的分片。
		    instream.skip(startPos);
		    UploadPartRequest uploadPartRequest = new UploadPartRequest();
		    uploadPartRequest.setBucketName(bucketName);
		    uploadPartRequest.setKey(objectName);
		    uploadPartRequest.setUploadId(uploadId);
		    uploadPartRequest.setInputStream(instream);
		    // 设置分片大小。除了最后一个分片没有大小限制，其他的分片最小为100KB。
		    uploadPartRequest.setPartSize(curPartSize);
		    // 设置分片号。每一个上传的分片都有一个分片号，取值范围是1~10000，如果超出这个范围，OSS将返回InvalidArgument的错误码。
		    uploadPartRequest.setPartNumber( i + 1);
		    // 每个分片不需要按顺序上传，甚至可以在不同客户端上传，OSS会按照分片号排序组成完整的文件。
		    UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
		    // 每次上传分片之后，OSS的返回结果会包含一个PartETag。PartETag将被保存到partETags中。
		    partETags.add(uploadPartResult.getPartETag());
		}


		// 创建CompleteMultipartUploadRequest对象。
		// 在执行完成分片上传操作时，需要提供所有有效的partETags。OSS收到提交的partETags后，会逐一验证每个分片的有效性。当所有的数据分片验证通过后，OSS将把这些分片组合成一个完整的文件。
		CompleteMultipartUploadRequest completeMultipartUploadRequest =
		        new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);

		// 如果需要在完成文件上传的同时设置文件访问权限，请参考以下示例代码。
		// completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.PublicRead);

		// 完成上传。
		CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest);
		toFile.delete();
		// 关闭OSSClient。
		ossClient.shutdown();
	}


}
